#include <pthread.h>
#include <string.h>

#include "db.h"
#include "log.h"
#include "db_info.h"
#include "db_ops.h"
#include "core_conf.h"

#include "mysql_ops.h"

extern struct core_conf core_conf;

struct db_ops *get_db_ops(void)
{
	log_info("begin get_db_ops.");

	struct db_ops *db_ops;

	struct db_info *db_info = core_conf.db_info; 
	if (db_info == NULL) {
		log_error("db_info is NULL.");
		return NULL;
	}

	pthread_mutex_lock(&(db_info->lock));

	if (db_info->count == 0) {
		pthread_mutex_unlock(&(db_info->lock));
		log_error("db_info->count == 0.");	
		return NULL;
	}

	/* TODO: Now we just select the database whose count is minimal. */
	unsigned short count = 100;
	struct db_data *db_data;
	struct db_data *tmp;
	tmp = db_info->db_list_head;
	db_data = NULL;

	while (tmp != NULL) {
		pthread_mutex_lock(&(tmp->lock));

		if (tmp->alive != 1) {
			pthread_mutex_unlock(&(tmp->lock));
			tmp = tmp->next;
			continue;
		}

		if (tmp->count < count) {
			count = tmp->count;
			db_data = tmp;
		}

		pthread_mutex_unlock(&(tmp->lock));

		tmp = tmp->next;
	}

	if (db_data == NULL) {
		log_error("no suitable db.");
		return NULL;
	}

	pthread_mutex_lock(&(db_data->lock));
	
	if (strcmp(db_data->db_type_name, "mysql") == 0) {
		db_ops = get_mysql_ops(db_data->db_name, db_data->db_user_name, db_data->db_passwd, db_data->db_address);

		if (db_ops == NULL) {
			log_error("get_mysql_ops failed.");
		}
	

		db_data->count++;

		pthread_mutex_unlock(&(db_data->lock));
		pthread_mutex_unlock(&(db_info->lock));

		return db_ops;
	} else { /* TODO: add other databases. */
		pthread_mutex_unlock(&(db_data->lock));
		pthread_mutex_unlock(&(db_info->lock));

		log_error("can't find %s's handler.", db_data->db_type_name);
		return NULL;
	}

	/* NOT REACHED HERE. */
	log_error("Oh...Bug...");
}
